package com.lbd.system.service.impl;

import com.lbd.base.service.BaseServiceImpl;
import com.lbd.system.bean.Menu;
import com.lbd.system.dao.MenuRepository;
import com.lbd.system.service.MenuService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.List;

/**
 * Created by WangYajie on 2016/9/19.
 */
@Service
@Transactional
public class MenuServiceImpl extends BaseServiceImpl<Menu, MenuRepository> implements MenuService {
    @Autowired
    MenuRepository menuRepository;

    @Override
    public String buildJpql(Menu menu, Map<String, Object> parameter) {
        StringBuilder jpqlBuilder = new StringBuilder(" from  Menu t ");
        if (menu != null) {
            if (StringUtils.isNotBlank(menu.getName())) {
                jpqlBuilder.append(" and  t.name like :name");
                parameter.put("name", "%" + menu.getName() + "%");
            }
            if (StringUtils.isNotBlank(menu.getCode())) {
                jpqlBuilder.append(" and  t.code like :code");
                parameter.put("code", "%" + menu.getCode() + "%");
            }
        }
        return jpqlBuilder.toString();
    }

    @Override
    @Transactional(readOnly = true)
    public List<Menu> loadUserMenu(String id) {
        String sql = " SELECT menu_id FROM sys_emp_role_menu rum WHERE EXISTS(SELECT role_id              FROM (SELECT role_id id                    FROM employee e LEFT JOIN sys_emp_role ur ON e.id = ur.emp_id                    WHERE e.id = :id) t              WHERE rum.role_id = t.id) UNION SELECT menu_id       FROM sys_emp_role_menu WHERE emp_id=:uid";
        //用户拥有的菜单
        Set<String> authorities = new HashSet<>(em.createNativeQuery(sql).setParameter("id", id).setParameter("uid", id).getResultList());
        List<Menu> menus = menuRepository.findByParentIsNull();
        setParentNull(menus);
        filterUserAuthority(menus, authorities);
        return menus;
    }

    @Override
    @Transactional(readOnly = true)
    public List<Menu> findByParentIsNull() {
        List<Menu> menus = menuRepository.findByParentIsNull();
        setParentNull(menus);
        return menus;
    }

    private void setParentNull(List<Menu> menus) {
        if (CollectionUtils.isEmpty(menus)) {
            return;
        }
        for (Menu menu : menus) {
            setParentNull(menu.getChildren());
            menu.setParent(null);
        }

    }

    /**
     * 过滤用户菜单
     *
     * @param menus       所有菜单
     * @param authorities 用户拥有菜单
     */
    private void filterUserAuthority(List<Menu> menus, Set<String> authorities) {
        if (CollectionUtils.isEmpty(menus)) {
            return;
        }
        Iterator<Menu> iterator = menus.iterator();
        while (iterator.hasNext()) {
            Menu menu = iterator.next();
            if (!authorities.contains(menu.getId())) {
                iterator.remove();
                continue;
            }
            filterUserAuthority(menu.getChildren(), authorities);
        }
    }
}
